/**
 * 嫌疑人身份聚合服务
 * 从各类数据中提取人员信息并建立"人-账号"映射关系
 */

class SubjectService {
    /**
     * 从案件数据中提取所有人员及其关联账号
     * @param {string} caseId 案件ID
     * @returns {Promise<Array>} 人员列表
     */
    static async extractSubjects(caseId) {
        if (!caseId) {
            throw new Error('案件ID不能为空');
        }

        try {
            // 1. 从银行流水中提取人员和银行卡号
            const bankSubjects = await this.extractFromBankTransactions(caseId);

            // 2. 从通话记录中提取人员和手机号
            const commSubjects = await this.extractFromCallRecords(caseId);

            // 3. 合并去重
            const mergedSubjects = this.mergeSubjects(bankSubjects, commSubjects);

            console.log(`[SubjectService] 从案件 ${caseId} 中提取到 ${mergedSubjects.length} 个人员`);
            return mergedSubjects;
        } catch (error) {
            console.error('[SubjectService] 提取人员失败:', error);
            throw error;
        }
    }

    /**
     * 从银行流水中提取人员和账号
     * 注：只提取账号持有人，不包含交易对手方（避免下拉框内容过多）
     */
    static async extractFromBankTransactions(caseId) {
        const sql = `
            SELECT DISTINCT
                customer_name as name,
                id_number as id_card,
                account_card as account_number
            FROM bank_transactions
            WHERE case_id = ?
                AND customer_name IS NOT NULL
                AND customer_name != ''
            ORDER BY customer_name
        `;

        const result = await window.electronAPI.data.query({
            caseId,
            sql,
            params: [caseId]
        });

        if (!result.success) {
            console.warn('[SubjectService] 银行流水查询失败:', result.message);
            return [];
        }

        console.log(`[SubjectService] 账号持有人数据行数: ${result.data.length}`);
        if (result.data.length > 0) {
            console.log('[SubjectService] 第一条数据示例:', result.data[0]);
        }

        // 按姓名+身份证聚合
        const subjectMap = new Map();

        result.data.forEach(row => {
            const key = `${row.name}_${row.id_card || 'unknown'}`;

            if (!subjectMap.has(key)) {
                subjectMap.set(key, {
                    id: this.generateSubjectId(row.name, row.id_card),
                    name: row.name,
                    idCard: row.id_card || null,
                    accounts: {
                        bank: [],
                        phone: [],
                        vehicle: []
                    },
                    dataSource: ['bank']
                });
            }

            const subject = subjectMap.get(key);
            if (row.account_number && !subject.accounts.bank.includes(row.account_number)) {
                subject.accounts.bank.push(row.account_number);
            }
        });

        const subjects = Array.from(subjectMap.values());
        console.log(`[SubjectService] 聚合后的银行人员数: ${subjects.length}`);
        if (subjects.length > 0) {
            console.log('[SubjectService] 第一个人员示例:', subjects[0]);
        }

        return subjects;
    }

    /**
     * 从通话记录中提取人员和手机号
     */
    static async extractFromCallRecords(caseId) {
        const sql = `
            SELECT DISTINCT
                user_name as name,
                user_number as phone
            FROM call_records
            WHERE case_id = ?
                AND user_name IS NOT NULL
                AND user_name != ''
            ORDER BY user_name
        `;

        const result = await window.electronAPI.data.query({
            caseId,
            sql,
            params: [caseId]
        });

        if (!result.success) {
            console.warn('[SubjectService] 通话记录查询失败:', result.message);
            return [];
        }

        // 按姓名聚合（通话记录通常没有身份证）
        const subjectMap = new Map();

        result.data.forEach(row => {
            const key = row.name; // 仅用姓名作为key

            if (!subjectMap.has(key)) {
                subjectMap.set(key, {
                    id: this.generateSubjectId(row.name, null),
                    name: row.name,
                    idCard: null,
                    accounts: {
                        bank: [],
                        phone: [],
                        vehicle: []
                    },
                    dataSource: ['call']
                });
            }

            const subject = subjectMap.get(key);
            if (row.phone && !subject.accounts.phone.includes(row.phone)) {
                subject.accounts.phone.push(row.phone);
            }
        });

        return Array.from(subjectMap.values());
    }

    /**
     * 合并不同来源的人员信息
     */
    static mergeSubjects(bankSubjects, commSubjects) {
        const mergedMap = new Map();

        // 先加入银行流水的人员（优先级更高，因为有身份证）
        bankSubjects.forEach(subject => {
            mergedMap.set(subject.name, subject);
        });

        // 合并通话记录的人员
        commSubjects.forEach(commSubject => {
            if (mergedMap.has(commSubject.name)) {
                // 已存在，合并手机号
                const existing = mergedMap.get(commSubject.name);
                commSubject.accounts.phone.forEach(phone => {
                    if (!existing.accounts.phone.includes(phone)) {
                        existing.accounts.phone.push(phone);
                    }
                });
                if (!existing.dataSource.includes('call')) {
                    existing.dataSource.push('call');
                }
            } else {
                // 新人员，直接添加
                mergedMap.set(commSubject.name, commSubject);
            }
        });

        return Array.from(mergedMap.values());
    }

    /**
     * 生成人员唯一ID
     */
    static generateSubjectId(name, idCard) {
        const base = idCard || name;
        return `subject_${this.hashCode(base)}`;
    }

    /**
     * 简单哈希函数
     */
    static hashCode(str) {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash; // Convert to 32bit integer
        }
        return Math.abs(hash).toString(36);
    }

    /**
     * 获取特定人员的详细信息
     * @param {string} caseId 案件ID
     * @param {string} subjectId 人员ID
     * @returns {Promise<Object>} 人员详情
     */
    static async getSubjectDetails(caseId, subjectId) {
        // 先提取所有人员
        const subjects = await this.extractSubjects(caseId);

        // 查找指定人员
        const subject = subjects.find(s => s.id === subjectId);

        if (!subject) {
            throw new Error(`未找到人员: ${subjectId}`);
        }

        // 可以在这里扩展，查询更多详细信息
        return subject;
    }

    /**
     * 缓存提取结果（避免重复查询）
     */
    static _cache = new Map();

    static async extractSubjectsWithCache(caseId) {
        if (this._cache.has(caseId)) {
            console.log('[SubjectService] 使用缓存结果');
            return this._cache.get(caseId);
        }

        const subjects = await this.extractSubjects(caseId);
        this._cache.set(caseId, subjects);
        return subjects;
    }

    static clearCache(caseId = null) {
        if (caseId) {
            this._cache.delete(caseId);
        } else {
            this._cache.clear();
        }
    }
}

// 暴露到全局
window.SubjectService = SubjectService;
